package siac.com.util;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Classe de tratamento de Datas.
 * 
 * @author Eduardo Mauricio Nsimba
 * @version 1.0, 23/06/2006
 * @since 1.0
 */
public class FormatarData implements Serializable {

	/**
	 * 
	 */
	private static Log LOG = LogFactory.getLog(FormatarData.class);

	private static final long serialVersionUID = 1L;

	private static List listaDeDiasUteisDoMes = new ArrayList();

	
	public static boolean isVerificarSeFeriado(Date data) {

		if (data.equals(obterDataHoje())) {
			return true;
		}

		return false;
	}

	public static String dataPagamento() throws ParseException {

		Calendar clnK;
		int nSemana = 0;
		String diaValor = "";

		clnK = Calendar.getInstance();
		nSemana = clnK.get(Calendar.DAY_OF_WEEK);

		// Adicionar dias a data actual
		switch (nSemana) {
		case 2:
			diaValor = adicionarDiasADataQualquer(new Date(), 2);
			// LOG.debug("Entrei na segunda*** : " + diaValor);
			break;
		case 3:
			diaValor = adicionarDiasADataQualquer(new Date(), 2);
			// LOG.debug("entrei ter�a*** : " + diaValor);
			break;
		case 4:
			diaValor = adicionarDiasADataQualquer(new Date(), 2);
			// LOG.debug("entrei quarta*** : " + diaValor);
			break;
		case 5:
			diaValor = adicionarDiasADataQualquer(new Date(), 4);
			// LOG.debug("entrei quinta*** : " + diaValor);
			break;
		case 6:
			diaValor = adicionarDiasADataQualquer(new Date(), 4);
			// LOG.debug("entrei sexta*** : " + diaValor);
			break;

		default:
			diaValor = "0";
			// LOG.debug("entrei no sabado ou domingo*** : " + diaValor);
			break; // Sabado ou Domingo

		}
		if (diaValor.contains("-")) {
			diaValor = diaValor.replaceAll(" -", "/");
		}

		// Se Verifica se feriado e fim semana
		diaValor = VerificarSeFimDeSemanaOuFeriado(converterStringEmData(diaValor));

		return diaValor;
	}

	public static String strData() throws Exception {
		String dia = Integer.toString(obterDia(new Date()));
		String mes = Integer.toString(obterMes(new Date()));
		String ano = Integer.toString(obterAno(new Date()));
		if (dia.length() == 1) {
			dia = "0" + dia;
		}
		if (mes.length() == 1) {
			mes = "0" + mes;
		}
		return dia + mes + ano;
	}
	
	public static String strDiaMes(Date data) throws Exception {
		String dia = Integer.toString(obterDia(data));
		String mes = Integer.toString(obterMes(data));
		if (dia.length() == 1) {
			dia = "0" + dia;
		}
		if (mes.length() == 1) {
			mes = "0" + mes;
		}
		return dia + mes;
	}
	
	public static String strHoraMinuto_Now(Date data) throws Exception {
		String h = Integer.toString(obterHora(data));
		String m = Integer.toString(obterMinuto(data));
		if (h.length() == 1) {
			h = "0" + h;
		}
		if (m.length() == 1) {
			m = "0" + m;
		}
		return h + m;
	}
	
	 public static String strHoraMinuto_Fim(String data) throws Exception {	
			return data.substring(0,2) + data.substring(3,5);
	 }
	 
	public static String AcrescentaZeroString(int dia) throws Exception {
		String diaLoc = "";
		if (Integer.toString(dia).length() == 1) {
			diaLoc = "0" + dia;
		}
		else{
			diaLoc = Integer.toString(dia);
		}
		return diaLoc;
	}
	
	public static Date dataVigorarTaxa() throws ParseException {

		Calendar clnK;
		int nSemana = 0;
		String diaValor;

		clnK = Calendar.getInstance();
		nSemana = clnK.get(Calendar.DAY_OF_WEEK);

		// Adicionar dias a data actual
		switch (nSemana) {
		case 2:
			diaValor = adicionarDiasADataQualquer(new Date(), 1);
			break;
		case 3:
			diaValor = adicionarDiasADataQualquer(new Date(), 1);
			break;
		case 4:
			diaValor = adicionarDiasADataQualquer(new Date(), 1);
			break;
		case 5:
			diaValor = adicionarDiasADataQualquer(new Date(), 1);
			break;
		case 6:
			diaValor = adicionarDiasADataQualquer(new Date(), 3);
			break;

		default:
			diaValor = "0";
			break; // Sabado ou Domingo
		}
		
		if (diaValor.contains("-")) {
			diaValor = diaValor.replaceAll(" -", "/");
		}

		diaValor = VerificarSeFimDeSemanaOuFeriado(converterStringEmData(diaValor));
		return converterStringEmData(diaValor);
	}

	public static String dataVigorarTaxa1() throws ParseException {

		Calendar clnK;
		int nSemana = 0;
		String diaValor;

		clnK = Calendar.getInstance();
		nSemana = clnK.get(Calendar.DAY_OF_WEEK);

		// Adicionar dias a data actual
		switch (nSemana) {
		case 2:
			diaValor = adicionarDiasADataQualquer(new Date(), 1);
			break;
		case 3:
			diaValor = adicionarDiasADataQualquer(new Date(), 1);
			break;
		case 4:
			diaValor = adicionarDiasADataQualquer(new Date(), 1);
			break;
		case 5:
			diaValor = adicionarDiasADataQualquer(new Date(), 1);
			break;
		case 6:
			diaValor = adicionarDiasADataQualquer(new Date(), 3);
			break;

		default:
			diaValor = "0";
			break; // Sabado ou Domingo
		}
		/*
		 * if(diaValor.contains("/")){ diaValor = diaValor.replaceAll(" /","-"); }
		 */

		if (diaValor.contains("-")) {
			diaValor = diaValor.replaceAll(" -", "/");
		}
		
		diaValor = VerificarSeFimDeSemanaOuFeriado(converterStringEmData(diaValor));
		return diaValor;
	}

	public static String VerificarSeFimDeSemanaOuFeriado(Date data)
			throws ParseException {

		String dataActual = adicionarDiasADataQualquer(data, 0);
		int nMonth, nDay;
		Calendar clnK;

		clnK = Calendar.getInstance();

		clnK.setTime(data);
		nMonth = clnK.get(Calendar.MONTH) + 1;
		nDay = clnK.get(Calendar.DAY_OF_MONTH);

		return dataActual;
	}

	public static boolean VerificarSeFimDeSemanaFeriado(Date data)
			throws ParseException {

		int nMonth, nDay;
		Calendar clnK;

		clnK = Calendar.getInstance();

		clnK.setTime(data);
		nMonth = clnK.get(Calendar.MONTH) + 1;
		nDay = clnK.get(Calendar.DAY_OF_MONTH);

		if (isVerificarSeFimDeSemana(data)) {
			return true;
		}

		return false;
	}

	// Verifica se dia � Domingo, e retorna true se verdadeiro
	public static boolean isVerificarSeDomingo(Date data) {

		Calendar diaSemana;
		int nDia = 0;

		// Obter dia de semana
		diaSemana = Calendar.getInstance();
		diaSemana.setTime(data);
		nDia = diaSemana.get(Calendar.DAY_OF_WEEK);

		if (Calendar.SUNDAY == nDia) { // se o dia for sabado
			return true;
		}

		return false;
	}

	// Verifica se dia � Sabado ou Domingo, e retorna true se verdadeiro
	public static boolean isVerificarSeSabado(Date data) {
		Calendar diaSemana;
		int nDia = 0;
		diaSemana = Calendar.getInstance();
		diaSemana.setTime(data);
		nDia = diaSemana.get(Calendar.DAY_OF_WEEK);
		if (Calendar.SATURDAY == nDia) {
			return true;
		}

		return false;
	}

	// Verifica se dia � Sabado ou Domingo, e retorna true se verdadeiro
	public static boolean isVerificarSeFimDeSemana(Date data) {
		Calendar diaSemana;
		int nDia = 0;
		diaSemana = Calendar.getInstance();
		diaSemana.setTime(data);
		nDia = diaSemana.get(Calendar.DAY_OF_WEEK);
		if ((Calendar.SATURDAY == nDia) || (Calendar.SUNDAY == nDia)) {
			return true;
		}
		return false;
	}

	public static String adicionarMinutosEmHoraAtual(int minuto) {
		Calendar calendar = new GregorianCalendar();
		calendar.add(Calendar.MINUTE, minuto);
		Date data = calendar.getTime();
		String hora = new SimpleDateFormat("HH:mm").format(data);
		return hora;
	}

	public static Date adicionarMinutosEmHoraAtualDt(int minuto) {
		Calendar calendar = new GregorianCalendar();
		calendar.add(Calendar.MINUTE, minuto);
		Date data = calendar.getTime();
		//String hora = new SimpleDateFormat("HH:mm").format(data);
		return data;
	}
	
	public static String adicionarDiasADataDeHoje(int dias) {
		return auxiliarDiasMes(obterDataHoje(), dias);
	}

	public static String adicionarDiasADataQualquer(Date data, int dias) {
		return auxiliarDiasMes(data, dias);
	}

	public static Date obterProximoFimDeSemana() {
		GregorianCalendar today = new GregorianCalendar();
		today.add(Calendar.DAY_OF_WEEK, Calendar.SATURDAY
				- today.get(Calendar.DAY_OF_WEEK));
		return today.getTime();
	}

	public String obterPrimeiroDiaDoMes(Date data) throws Exception {
		Calendar clnK;
		GregorianCalendar cal;
		int mes = 0, ano;
		clnK = Calendar.getInstance();
		clnK.setTime(data);

		ano = clnK.get(Calendar.YEAR);
		mes = clnK.get(Calendar.MONTH) + 1;

		if (mes == 0) {
			mes = 12;
			ano = ano - 1;
		}
		return "01" + "/" + mes + "/" + ano;
	}

	public String obterUltimaDiaDoMes(Date data) throws Exception {
		Calendar clnK;
		GregorianCalendar cal;
		int mes = 0, ano, dia;
		clnK = Calendar.getInstance();
		clnK.setTime(data);

		ano = clnK.get(Calendar.YEAR);
		mes = clnK.get(Calendar.MONTH) + 1;

		cal = new GregorianCalendar(ano, mes, 01);
		dia = numeroDiasMes(mes, ano);
		if (mes == 0) {
			mes = 12;
			ano = ano - 1;
		}
		return dia + "/" + mes + "/" + ano;
	}

	public static int obterHora(Date data) throws Exception {
		Calendar clnK;
		int h = 0;
		clnK = Calendar.getInstance();
		clnK.setTime(data);
		h = clnK.get(Calendar.HOUR_OF_DAY ); // numeroDiasMes(mes, ano);
		return h;
	}
	
	public static int obterMinuto(Date data) throws Exception {
		Calendar clnK;
		int m = 0;
		clnK = Calendar.getInstance();
		clnK.setTime(data);
		m = clnK.get(Calendar.MINUTE); // numeroDiasMes(mes, ano);
		return m;
	}
	public static int obterDia(Date data) throws Exception {
		Calendar clnK;
		int dia = 0;
		clnK = Calendar.getInstance();
		clnK.setTime(data);
		dia = clnK.get(Calendar.DAY_OF_MONTH); // numeroDiasMes(mes, ano);
		return dia;
	}

	public static int obterMes(Date data) throws Exception {
		Calendar clnK;
		int mes = 0;
		clnK = Calendar.getInstance();
		clnK.setTime(data);
		mes = clnK.get(Calendar.MONTH) + 1;
		return mes;
	}

	public static int obterAno(Date data) throws Exception {
		Calendar clnK;
		int ano = 0;
		clnK = Calendar.getInstance();
		clnK.setTime(data);
		ano = clnK.get(Calendar.YEAR);
		return ano;
	}


	public static int obterDiasUteisDoMesCorrente(List listaFeriado,
			List listaDeDiasUteis) throws Exception {
		boolean achou = false;
		int numDia = FormatarData.numeroDiasMes(FormatarData.obterMes(new Date()),
				FormatarData.obterAno(new Date()));
		for (int i = 0; i <= numDia; i++) {
			achou = false;
			Date d = new SimpleDateFormat("dd/MM/yyyy").parse(i + "/"
					+ FormatarData.obterMes(new Date()) + "/"
					+ FormatarData.obterAno(new Date()));
			for (int j = 0; j < listaFeriado.size(); j++) {
				if ((i + "" + FormatarData.obterMes(new Date()))
						.equals(listaFeriado.get(j))) {
					achou = true;
					break;
				}
			}
			if (!achou) {
				listaDeDiasUteis.add(d);

			}
		}
		return listaDeDiasUteis.size();
	}

	private static int numeroDiasMes(int mes, int ano) {
		int dias = 31;
		switch (mes) {
		case 2:
			if (bisiesto(ano))
				dias = 29;
			else
				dias = 28;
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			dias = 30;
			break;
		}
		return dias;
	}

	private static boolean bisiesto(int ano) {
		return ((ano % 4 == 0 && ano % 100 != 0) || (ano % 400 == 0));
	}

	public static String obterAnoCorrente() {
		return Integer.toString(obterData().get(Calendar.YEAR));
	}

	public static String obterAnoAnterior() {
		return Integer.toString(obterData().get(Calendar.YEAR) - 1);
	}

	public static String obterAnoProximo() {
		return Integer.toString(obterData().get(Calendar.YEAR) + 1);
	}

	public static String obterMesDataAtual() {
		return Integer.toString(obterData().get(Calendar.MONTH));
	}

	public static String obterDiaDataAtual() {
		return Integer.toString(obterData().get(Calendar.DAY_OF_MONTH));
	}

	public static Date obterDataHoje() {
		return new Date();
	}

	private static Calendar obterInicioDeDia(Calendar calendar) {
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
				calendar.get(Calendar.DATE), 0, 0, 0);
		return calendar;
	}

	private static Calendar obterFimDeDia(Calendar calendar) {
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
				calendar.get(Calendar.DATE), 23, 59, 59);
		return calendar;
	}

	public static String auxiliarDiasMes(Date data, int dias) {

		int nAno, nMes, nDia;
		Calendar clnK;

		clnK = Calendar.getInstance();
		clnK.setTime(data);

		nAno = clnK.get(Calendar.YEAR);
		nMes = clnK.get(Calendar.MONTH);
		nDia = clnK.get(Calendar.DAY_OF_MONTH);

		GregorianCalendar mortgage = new GregorianCalendar(nAno, nMes, nDia);
		mortgage.add(Calendar.DAY_OF_MONTH, dias);
		Date d = mortgage.getTime();
		DateFormat df = new SimpleDateFormat("dd/MM/yyyy");

		String s = df.format(d);

		return s;
	}

	public static Calendar obterData() {
		Calendar clnK;
		clnK = Calendar.getInstance();
		clnK.setTime(obterDataHoje());
		return clnK;
	}

	public static Date converterStringEmData(String data) {
		Date df = null;
		try {
			df = new SimpleDateFormat("dd/MM/yyyy").parse(data);
		} catch (Exception err) {
			System.out.print("erro");
		}

		return df;
	}

	public static Date obterInicioDaUltimaSemana() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_WEEK, -(7 + calendar
				.get(Calendar.DAY_OF_WEEK) - 1));
		return obterInicioDeDia(calendar).getTime();
	}

	public static Date obterFimUltimaSemanaEndLastWeek() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_WEEK, -calendar.get(Calendar.DAY_OF_WEEK));
		return obterFimDeDia(calendar).getTime();
	}

	public static Date obterInicioDessaSemana() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_WEEK,
				-calendar.get(Calendar.DAY_OF_WEEK) + 1);
		return obterInicioDeDia(calendar).getTime();
	}

	public static Date obterFimDessaSemana() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_WEEK,
				-calendar.get(Calendar.DAY_OF_WEEK) + 7);
		return obterFimDeDia(calendar).getTime();
	}

	public static Date obterInicioDaProximaSemana() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_WEEK,
				-calendar.get(Calendar.DAY_OF_WEEK) + 7 + 1);
		return obterInicioDeDia(calendar).getTime();
	}

	public static Date obterUltimoFimSemana() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_WEEK,
				-calendar.get(Calendar.DAY_OF_WEEK) + 7 + 7);
		return obterFimDeDia(calendar).getTime();
	}

	public static Date getStartCurrentDate() {
		Calendar calendar = Calendar.getInstance();
		return obterInicioDeDia(calendar).getTime();
	}

	public static Date getEndCurrentDate() {
		Calendar calendar = Calendar.getInstance();
		return obterFimDeDia(calendar).getTime();
	}

	public static List obterListaDeDatasUteis(Date data) throws Exception {
		FormatarData ud = new FormatarData();
		for (int i = 0; i < obterDia(data); i++) {
			if (!isVerificarSeFimDeSemana(new SimpleDateFormat("dd/MM/yyyy")
					.parse(adicionarDiasADataQualquer(new SimpleDateFormat(
							"dd/MM/yyyy").parse(i + "/" + obterMes(data) + "/"
							+ obterAno(data)), 1)))) {
				ud.listaDeDiasUteisDoMes.add(adicionarDiasADataQualquer(
						new SimpleDateFormat("dd/MM/yyyy").parse(i + "/"
								+ obterMes(data) + "/" + obterAno(data)), 1));
			}
		}
		return ud.listaDeDiasUteisDoMes;
	}
	
   public static int calculoTempoFecho( int TempoTotal,String strHoraInicio) throws NumberFormatException, Exception {
	     
	   Calendar agora = Calendar.getInstance();
	     int ho = agora.get(Calendar.HOUR_OF_DAY);
	     int mi = agora.get(Calendar.MINUTE);   
	     int tempo = 0;
     
	     String horaInicio = strHoraInicio.substring(0,2);
	     String minutoInicio = strHoraInicio.substring(3,5);
      
	     if (horaInicio.substring(0,1).equals("0")){
	    	 horaInicio = strHoraInicio.substring(1,2); 
	     }
          
	     if(horaInicio.equals( Integer.toString(ho))){//AcrescentaZeroString(ho)
	        tempo = TempoTotal - (mi- Integer.parseInt(minutoInicio)); 
	     }
	     else{
	       minutoInicio = Integer.toString((60 - Integer.parseInt(minutoInicio)) +  mi);
	       tempo = TempoTotal - Integer.parseInt(minutoInicio);
	     } 	
	    
	 return tempo;
  }
	
  
	/**
	 * @return Returns the listaDeDiasUteisDoMes.
	 */
	public static synchronized List getListaDeDiasUteisDoMes() {
		return listaDeDiasUteisDoMes;
	}

	/**
	 * @param listaDeDiasUteisDoMes The listaDeDiasUteisDoMes to set.
	 */
	public static synchronized void setListaDeDiasUteisDoMes(
			List listaDeDiasUteisDoMes) {
		FormatarData.listaDeDiasUteisDoMes = listaDeDiasUteisDoMes;
	}

}
